package com.unit.manager;

import java.util.Map;

import javax.inject.Named;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.unit.csv.CSVFileReader;
import com.unit.domain.TestDataContext;
import com.unit.enumeration.CsvCharset;
import com.unit.util.TimeUtil;

@Named("testDataManager")
public class TestDataManager {

	private Logger log = LoggerFactory.getLogger(getClass());	
	
	public TestDataContext loadDataContext(String csvPath, String dbType) {
		return baseLoadDataContextToMap(csvPath, "id", dbType, CsvCharset.UTF);
	}
	
	public TestDataContext loadDataContextByMysql(String csvPath) {
		return baseLoadDataContextToMap(csvPath, "id", "mysql", CsvCharset.UTF);
	}
	
	public TestDataContext baseLoadDataContextToMap(String csvPath, String PKColumn, String dbType, CsvCharset charset){
		TestDataContext dataContext = new TestDataContext();
		dataContext.csvPath = csvPath;
		dataContext.idColumn = StringUtils.isBlank(PKColumn) ? "id" :PKColumn;
		dataContext.csvCharset = charset == null ? CsvCharset.UTF : charset;
		
		if (StringUtils.isBlank(dbType)) {
			dataContext.dbType = "oracle";
		} else {
			dataContext.dbType = dbType;
		}
		try {			
			CSVFileReader reader = new CSVFileReader(csvPath, dataContext.csvCharset);
			dataContext.tableName = reader.getTableName();
			dataContext.columnNameList = reader.getTableColumn();
			dataContext.dataBeforeTest = reader.getBerforeDataMap();
			dataContext.dataAfterTest = reader.getAfterDataMap();					
			return dataContext;
		} catch (Exception e) {
			String msg = "{path:'"+ csvPath +"'}";
			log.error(msg, e);
			throw new RuntimeException(msg, e);
		}
	}
	
	public void putCsvDataToDb(QueryRunner queryRunner, TestDataContext dataContext, Long[] idList) throws Exception {
		for (long id : idList) {
			Map<String, String> lineMap = dataContext.dataBeforeTest.get(id);
			if(lineMap == null || lineMap.isEmpty()) {
				throw new Exception("{msg:'初始ID:["+id+"]数据未准备'}");
			}
			String[] columnList = dataContext.columnNameList;
			String insertSql = buildInsertSql(dataContext.tableName, columnList, lineMap, dataContext.isOracle());
			
			Object[] param = new Object[columnList.length];
			for (int i = 0; i<columnList.length; i++) {
				String value = lineMap.get(columnList[i]);
				if(StringUtils.isBlank(value) || "null".equals(value.trim())) {
					param[i] = null;
				}else {
					param[i] = value;
				}
			}
			int effect = queryRunner.update(insertSql,param);
			if(effect == 0) {
				throw new Exception("{msg:'csv数据ID:["+id+"] 插入失败'}");
			}else if( effect >= 2) {
				throw new Exception("{msg:'csv数据ID:["+id+"] 插入多次'}");
			}			
		}
	}
	
	public String buildInsertSql(String tableName, String[] columnNameList, Map<String, String> lineMap, boolean isOracle) {
		StringBuilder columnPart = new StringBuilder(1000);
		StringBuilder valuePart = new StringBuilder(1000);		
		for (String columnName : columnNameList) {
			columnPart.append(columnName).append(',');
			
			String value = lineMap.get(columnName);			
			if (isOracle) {
				if (TimeUtil.isTimeString(value)) {
					valuePart.append("to_date(?, 'yyyy-mm-dd hh24:mi:ss'),");
				} else if(TimeUtil.isDateString(value)) {					
					valuePart.append("to_date(?, 'yyyy-mm-dd'),");
				}else {
					valuePart.append("?,");
				}
			}else {
				valuePart.append("?,");
			}
		}
		StringBuilder sql = new StringBuilder(2000);
		sql.append("insert into " + tableName + "(");
		sql.append(columnPart.deleteCharAt(columnPart.length() - 1));
		sql.append(") values(");
		sql.append(valuePart.deleteCharAt(valuePart.length() - 1)).append(')');

		return sql.toString();
	}
}
